using Microsoft.AspNetCore.SignalR;
using WeatherSystem.API.Models;
using WeatherSystem.API.Services;

namespace WeatherSystem.API.Hubs
{
    /// <summary>
    /// 天气数据实时推送Hub
    /// </summary>
    public class WeatherHub : Hub
    {
        private readonly ILogger<WeatherHub> _logger;
        private readonly IWeatherService _weatherService;

        public WeatherHub(
            ILogger<WeatherHub> logger,
            IWeatherService weatherService)
        {
            _logger = logger;
            _weatherService = weatherService;
        }

        /// <summary>
        /// 客户端连接时
        /// </summary>
        public override async Task OnConnectedAsync()
        {
            var connectionId = Context.ConnectionId;
            var userAgent = Context.GetHttpContext()?.Request.Headers["User-Agent"].ToString();
            
            _logger.LogInformation("客户端连接: {ConnectionId}, UserAgent: {UserAgent}", 
                connectionId, userAgent);

            // 发送欢迎消息
            await Clients.Caller.SendAsync("Connected", new
            {
                connectionId = connectionId,
                message = "已连接到天气数据实时推送服务",
                timestamp = DateTime.UtcNow
            });

            await base.OnConnectedAsync();
        }

        /// <summary>
        /// 客户端断开连接时
        /// </summary>
        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            var connectionId = Context.ConnectionId;
            
            if (exception != null)
            {
                _logger.LogWarning(exception, "客户端异常断开: {ConnectionId}", connectionId);
            }
            else
            {
                _logger.LogInformation("客户端正常断开: {ConnectionId}", connectionId);
            }

            // 从所有组中移除
            await Groups.RemoveFromGroupAsync(connectionId, "AllCities");
            
            await base.OnDisconnectedAsync(exception);
        }

        /// <summary>
        /// 订阅所有城市的天气更新
        /// </summary>
        public async Task SubscribeToAllCities()
        {
            var connectionId = Context.ConnectionId;
            
            await Groups.AddToGroupAsync(connectionId, "AllCities");
            
            _logger.LogDebug("客户端 {ConnectionId} 订阅了所有城市天气更新", connectionId);
            
            await Clients.Caller.SendAsync("SubscriptionConfirmed", new
            {
                type = "AllCities",
                message = "已订阅所有城市天气更新",
                timestamp = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 订阅特定城市的天气更新
        /// </summary>
        public async Task SubscribeToCity(string cityId)
        {
            var connectionId = Context.ConnectionId;
            
            if (!Guid.TryParse(cityId, out var parsedCityId))
            {
                await Clients.Caller.SendAsync("Error", new
                {
                    message = "无效的城市ID格式",
                    timestamp = DateTime.UtcNow
                });
                return;
            }

            var groupName = $"City_{cityId}";
            await Groups.AddToGroupAsync(connectionId, groupName);
            
            _logger.LogDebug("客户端 {ConnectionId} 订阅了城市 {CityId} 的天气更新", 
                connectionId, cityId);
            
            await Clients.Caller.SendAsync("SubscriptionConfirmed", new
            {
                type = "City",
                cityId = cityId,
                message = $"已订阅城市 {cityId} 的天气更新",
                timestamp = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 取消订阅特定城市
        /// </summary>
        public async Task UnsubscribeFromCity(string cityId)
        {
            var connectionId = Context.ConnectionId;
            
            if (!Guid.TryParse(cityId, out var parsedCityId))
            {
                await Clients.Caller.SendAsync("Error", new
                {
                    message = "无效的城市ID格式",
                    timestamp = DateTime.UtcNow
                });
                return;
            }

            var groupName = $"City_{cityId}";
            await Groups.RemoveFromGroupAsync(connectionId, groupName);
            
            _logger.LogDebug("客户端 {ConnectionId} 取消订阅城市 {CityId} 的天气更新", 
                connectionId, cityId);
            
            await Clients.Caller.SendAsync("UnsubscriptionConfirmed", new
            {
                type = "City",
                cityId = cityId,
                message = $"已取消订阅城市 {cityId} 的天气更新",
                timestamp = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 取消订阅所有城市
        /// </summary>
        public async Task UnsubscribeFromAllCities()
        {
            var connectionId = Context.ConnectionId;
            
            await Groups.RemoveFromGroupAsync(connectionId, "AllCities");
            
            _logger.LogDebug("客户端 {ConnectionId} 取消订阅所有城市天气更新", connectionId);
            
            await Clients.Caller.SendAsync("UnsubscriptionConfirmed", new
            {
                type = "AllCities",
                message = "已取消订阅所有城市天气更新",
                timestamp = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 获取当前连接状态
        /// </summary>
        public async Task GetConnectionStatus()
        {
            var connectionId = Context.ConnectionId;
            
            await Clients.Caller.SendAsync("ConnectionStatus", new
            {
                connectionId = connectionId,
                connected = true,
                timestamp = DateTime.UtcNow,
                message = "连接正常"
            });
        }

        /// <summary>
        /// 请求特定城市的最新天气数据
        /// </summary>
        public async Task RequestLatestWeather(string cityId)
        {
            try
            {
                if (!Guid.TryParse(cityId, out var parsedCityId))
                {
                    await Clients.Caller.SendAsync("Error", new
                    {
                        message = "无效的城市ID格式",
                        timestamp = DateTime.UtcNow
                    });
                    return;
                }

                var weatherData = await _weatherService.GetLatestWeatherAsync(parsedCityId);
                
                if (weatherData == null)
                {
                    await Clients.Caller.SendAsync("WeatherDataNotFound", new
                    {
                        cityId = cityId,
                        message = "未找到该城市的天气数据",
                        timestamp = DateTime.UtcNow
                    });
                    return;
                }

                await Clients.Caller.SendAsync("LatestWeatherData", new
                {
                    cityId = cityId,
                    data = weatherData,
                    timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取城市 {CityId} 最新天气数据失败", cityId);
                
                await Clients.Caller.SendAsync("Error", new
                {
                    message = "获取天气数据失败",
                    error = ex.Message,
                    timestamp = DateTime.UtcNow
                });
            }
        }
    }

    /// <summary>
    /// 天气数据推送服务
    /// </summary>
    public interface IWeatherNotificationService
    {
        Task NotifyWeatherUpdateAsync(Dictionary<string, object> weatherData);
        Task NotifyDataCollectionStartAsync();
        Task NotifyDataCollectionCompleteAsync(int successCount, int errorCount);
        Task NotifySystemStatusAsync(string status, string message);
    }

    /// <summary>
    /// 天气数据推送服务实现
    /// </summary>
    public class WeatherNotificationService : IWeatherNotificationService
    {
        private readonly IHubContext<WeatherHub> _hubContext;
        private readonly ILogger<WeatherNotificationService> _logger;

        public WeatherNotificationService(
            IHubContext<WeatherHub> hubContext,
            ILogger<WeatherNotificationService> logger)
        {
            _hubContext = hubContext;
            _logger = logger;
        }



        /// <summary>
        /// 推送天气数据更新（动态结构）
        /// </summary>
        public async Task NotifyWeatherUpdateAsync(Dictionary<string, object> weatherData)
        {
            try
            {
                var notification = new
                {
                    type = "WeatherUpdate",
                    cityId = weatherData.TryGetValue("cityId", out var cityIdValue) ? cityIdValue : null,
                    data = weatherData,
                    timestamp = DateTime.UtcNow
                };

                // 推送给订阅所有城市的客户端
                await _hubContext.Clients.Group("AllCities")
                    .SendAsync("WeatherUpdate", notification);

                // 推送给订阅特定城市的客户端
                if (cityIdValue != null)
                {
                    var cityGroup = $"City_{cityIdValue}";
                    await _hubContext.Clients.Group(cityGroup)
                        .SendAsync("WeatherUpdate", notification);
                }

                _logger.LogDebug("已推送城市 {CityId} 的天气更新", cityIdValue);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "推送天气更新失败");
            }
        }

        /// <summary>
        /// 推送数据采集开始通知
        /// </summary>
        public async Task NotifyDataCollectionStartAsync()
        {
            try
            {
                var notification = new
                {
                    type = "DataCollectionStart",
                    message = "数据采集已开始",
                    timestamp = DateTime.UtcNow
                };

                await _hubContext.Clients.All.SendAsync("SystemNotification", notification);
                
                _logger.LogDebug("已推送数据采集开始通知");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "推送数据采集开始通知失败");
            }
        }

        /// <summary>
        /// 推送数据采集完成通知
        /// </summary>
        public async Task NotifyDataCollectionCompleteAsync(int successCount, int errorCount)
        {
            try
            {
                var notification = new
                {
                    type = "DataCollectionComplete",
                    message = $"数据采集完成，成功: {successCount}, 失败: {errorCount}",
                    successCount = successCount,
                    errorCount = errorCount,
                    timestamp = DateTime.UtcNow
                };

                await _hubContext.Clients.All.SendAsync("SystemNotification", notification);
                
                _logger.LogDebug("已推送数据采集完成通知");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "推送数据采集完成通知失败");
            }
        }

        /// <summary>
        /// 推送系统状态通知
        /// </summary>
        public async Task NotifySystemStatusAsync(string status, string message)
        {
            try
            {
                var notification = new
                {
                    type = "SystemStatus",
                    status = status,
                    message = message,
                    timestamp = DateTime.UtcNow
                };

                await _hubContext.Clients.All.SendAsync("SystemNotification", notification);
                
                _logger.LogDebug("已推送系统状态通知: {Status}", status);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "推送系统状态通知失败");
            }
        }
    }
}